package com.refactor.practice.xutao.service.impl;

import com.refactor.practice.xutao.constants.MovieConstants;
import com.refactor.practice.xutao.enums.MovieTypeEnum;
import com.refactor.practice.xutao.model.Customer;
import com.refactor.practice.xutao.model.Movie;
import com.refactor.practice.xutao.service.MovieRentalService;

import java.util.Arrays;

/**
 * @Author xutao
 * @Date 2024/9/14 15:19
 * @Description: 影片租用实现类
 * 采用面向接口加配置类加枚举思想实现面向对象 后续有更改只需更改相对应的配置 新增功能只需新增接口 实现功能解偶
 * 也可采用模版策略模式定义各类型价格消费 实现功能解偶
 * @Version 1.0
 **/
public class MovieRentalServiceImpl implements MovieRentalService {

    @Override
    public Customer getComputedScore(Customer customer) {
        if(!customer.getMovies().isEmpty()){
            return computedScore(customer);
        }
        return customer;
    }

    @Override
    public Customer getComputedMoney(Customer customer) {
        if(!customer.getMovies().isEmpty()){
            return computedMoney(customer);
        }
        return customer;
    }

    /**
     * 租用影片新增积分计算
     * @param customer 客户
     * @return score
     */
    private Customer computedScore(Customer customer){
        int score = 0;
        if(!customer.getMovies().isEmpty()){
            score = customer.getMovies().stream().mapToInt(movie -> movie.getMovieType().getScore()).sum();
        }else {
            System.out.println("movies为空！");
        }
        customer.setScore(customer.getScore() + score);
        customer.setConsumeScore(score);
        return customer;
    }

    /**
     * 租用影片费用计算
     * @param customer 客户
     * @return 客户
     */
    private Customer computedMoney(Customer customer){
        double money = 0;
        if(!customer.getMovies().isEmpty()){
            for (Movie movie : customer.getMovies()) {
                switch (movie.getMovieType()){
                    case CHILDREN_MOVIE:
                        double childResult = computedMoney(movie.getDayRented(), MovieConstants.CHILDREN_MOVIE_PRICE, MovieConstants.CHILDREN_MOVIE_DISCOUNTS_PRICE,
                                MovieConstants.CHILDREN_MOVIE_DISCOUNTS_WHEN_DAY, movie.getMovieType());
                        movie.setMoney(childResult);
                        money += childResult;
                        break;
                    case REGULAR_MOVIE:
                        double regularResult = computedMoney(movie.getDayRented(), MovieConstants.REGULAR_MOVIE_PRICE, MovieConstants.REGULAR_MOVIE_DISCOUNTS_PRICE,
                                MovieConstants.REGULAR_MOVIE_DISCOUNTS_WHEN_DAY, movie.getMovieType());
                        movie.setMoney(regularResult);
                        money += regularResult;
                        break;
                    case NEW_MOVIE:
                        double newResult = computedMoney(movie.getDayRented(), MovieConstants.NEW_MOVIE_PRICE, MovieConstants.NEW_MOVIE_DISCOUNTS_PRICE,
                                MovieConstants.NEW_MOVIE_DISCOUNTS_WHEN_DAY, movie.getMovieType());
                        movie.setMoney(newResult);
                        money += newResult;
                        break;
                    default:
                        System.out.println("Unknown MovieType");
                }
            }
            // 需金额校验
            customer.setBalance(customer.getBalance() - money);
        }else {
            System.out.println("movies为空！");
        }
        return customer;
    }

    /**
     * 单个影片消费计算
     * @param dayRented 租用时间
     * @param price 价格
     * @param discountPrice 折扣价格
     * @param whenDiscountPriceDay 开始折扣价格天数
     * @param movieTypeEnum 影片类型
     * @return result
     */
    private double computedMoney(int dayRented, double price, double discountPrice, int whenDiscountPriceDay,  MovieTypeEnum movieTypeEnum) {
        System.out.println(movieTypeEnum.getDesc() + "租用天数：" + dayRented + "价格：" + price + " " + whenDiscountPriceDay + "天后优惠价格" + discountPrice );
        double result = 0;
        if (dayRented > whenDiscountPriceDay) {
            double money1 = whenDiscountPriceDay * price;
            double money2 = (dayRented - whenDiscountPriceDay) * discountPrice;
            result = money1 + money2;
        } else {
            result = dayRented * price;
        }
        System.out.println(movieTypeEnum.getDesc() + "消费金额:" + result);
        return result;
    }

    public static void main(String[] args) {
        MovieRentalService movieRentalService = new MovieRentalServiceImpl();
        // 模拟消费者本次消费情况
        Customer customer = new Customer();
        customer.setConsumeScore(0);
        customer.setScore(100);
        customer.setBalance(500);
        customer.setCustomerCode("123456");
        Movie movie1 = new Movie();
        movie1.setMovieType(MovieTypeEnum.CHILDREN_MOVIE);
        movie1.setDayRented(5);
        movie1.setMovieCode("xxx");
        movie1.setMovieTitle("西游记");
        Movie movie2 = new Movie();
        movie2.setMovieType(MovieTypeEnum.REGULAR_MOVIE);
        movie2.setDayRented(3);
        movie2.setMovieCode("zzz");
        movie2.setMovieTitle("水浒传");
        customer.setMovies(Arrays.asList(movie1,movie2));
        Customer computedMoney = movieRentalService.getComputedMoney(customer);
        Customer customerAll = movieRentalService.getComputedScore(computedMoney);
        // 打印本次消费详情
        System.out.println(customerAll.toString());
    }
}
